from django.shortcuts import render
from django.shortcuts import HttpResponseRedirect
from django.shortcuts import HttpResponse
from alipay.aop.api.AlipayClientConfig import AlipayClientConfig  # 客户端配置类
from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient  # 默认客户端类
from alipay.aop.api.domain.AlipayTradePagePayModel import AlipayTradePagePayModel  # 网站支付数据模型类
from alipay.aop.api.request.AlipayTradePagePayRequest import AlipayTradePagePayRequest  # 网站支付请求类
from alipay.aop.api.util.SignatureUtils import verify_with_rsa
from alipaydemo3 import settings
import random


def buy(request):
    return render(request, 'buy.html')


def to_pay(request):
    alipay_client_config = AlipayClientConfig()  # 创建配置对象
    alipay_client_config.server_url = settings.ALIPAY_URL  # 网关
    alipay_client_config.app_id = settings.ALIPAY_APPID  # APPID
    alipay_client_config.app_private_key = settings.APP_PRIVATE_KEY  # 应用私钥
    client = DefaultAlipayClient(alipay_client_config=alipay_client_config)  # 使用配置创建客户端
    model = AlipayTradePagePayModel()  # 创建网站支付模型
    model.out_trade_no = 'order_%s' % random.randrange(100000, 999999)  # 商户订单号码
    model.total_amount = int(request.GET['quantity']) * float(request.GET['price'])  # 支付总额
    model.subject = request.GET['goods_name']  # 订单标题
    model.body = '一套完整详细的Python入门视频。'  # 订单描述
    model.product_code = 'FAST_INSTANT_TRADE_PAY'  # 与支付宝签约的产品码名称，目前只支持这一种。
    model.timeout_express = '30m'  # 订单过期关闭时长（分钟）
    pay_request = AlipayTradePagePayRequest(biz_model=model)  # 通过模型创建请求对象
    pay_request.return_url = settings.ALIPAY_NOTIFY_URL
    pay_request.notify_url = settings.ALIPAY_NOTIFY_URL  # 设置回调通知地址
    response = client.page_execute(pay_request, http_method='GET')  # 获取支付链接
    return HttpResponseRedirect(response)  # 重定向到支付宝支付页面


def pay_result(request):  # 定义处理回调通知的函数
    if request.method == 'GET':
        params = request.GET.dict()  # 获取参数字典
        if check_pay(params):  # 调用检查支付结果的函数
            '''
                此处编写支付成功后的业务逻辑
            '''
            return HttpResponse('支付成功！')
        else:
            '''
                此处编写支付失败后的业务逻辑
            '''
            return HttpResponse('支付失败！')
    if request.method == 'POST':
        params = request.POST.dict()  # 获取参数字典
        if check_pay(params):  # 调用检查支付结果的函数
            '''
                此处编写支付成功后的业务逻辑
            '''
            # print('支付成功！')
            return HttpResponse('success')  # 返回成功信息到支付宝服务器
        else:
            '''
                此处编写支付失败后的业务逻辑
            '''
            return HttpResponse('')


def check_pay(params):  # 定义检查支付结果的函数
    sign = params.pop('sign', None)  # 取出签名
    params.pop('sign_type')  # 取出签名类型
    params = sorted(params.items(), key=lambda e: e[0], reverse=False)  # 取出字典元素按key的字母升序排序形成列表
    message = "&".join(u"{}={}".format(k, v) for k, v in params).encode()  # 将列表转为二进制参数字符串
    # with open(settings.ALIPAY_PUBLIC_KEY_PATH, 'rb') as public_key: # 打开公钥文件
    try:
        #     status =verify_with_rsa(public_key.read().decode(),message,sign) # 验证签名并获取结果
        status = verify_with_rsa(settings.ALIPAY_PUBLIC_KEY.encode('utf-8').decode('utf-8'), message,
                                 sign)  # 验证签名并获取结果
        return status  # 返回验证结果
    except:  # 如果验证失败，返回假值。
        return False
